package unifor.mia.redes.protocoloconfiavel;


import java.awt.Color;
import java.awt.Font;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.ParallelGroup;
import javax.swing.GroupLayout.SequentialGroup;
import javax.swing.JLabel;
import javax.swing.text.AbstractDocument;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.DocumentFilter;
import unifor.mia.redes.relprotocol.CommunicationMonitor;
import unifor.mia.redes.relprotocol.ReliableReceiver;
import unifor.mia.redes.relprotocol.ReliableSender;
import unifor.mia.redes.relprotocol.msg.Pacote;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * DemoProtocoloConfiavel.java
 *
 * Created on 16/04/2011, 11:48:34
 */
/**
 *
 * @author marcelo
 */
public class DemoProtocoloConfiavel extends javax.swing.JFrame implements CommunicationMonitor{

    private static int MAX_CHARACTERS = 100;
    
    /** Creates new form DemoProtocoloConfiavel */
    public DemoProtocoloConfiavel() {
        initComponents();
        initSpecialComponents();
        configComponents();
        
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
   // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
   private void initComponents() {

      jButton1 = new javax.swing.JButton();
      jFormattedTextField1 = new javax.swing.JFormattedTextField();
      jLabel1 = new javax.swing.JLabel();
      pnlSender = new javax.swing.JPanel();
      pnlReceiver = new javax.swing.JPanel();
      jLabel2 = new javax.swing.JLabel();
      jLabel3 = new javax.swing.JLabel();
      jLabel4 = new javax.swing.JLabel();
      jLabel6 = new javax.swing.JLabel();
      jLabel7 = new javax.swing.JLabel();
      jLabel8 = new javax.swing.JLabel();
      jLabel9 = new javax.swing.JLabel();
      lbDescartadosErro = new javax.swing.JLabel();
      lbForaDeOrdem = new javax.swing.JLabel();
      menuBar = new javax.swing.JMenuBar();
      fileMenu = new javax.swing.JMenu();
      exitMenuItem = new javax.swing.JMenuItem();

      setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

      jButton1.setMnemonic('E');
      jButton1.setText("Enviar");
      jButton1.setToolTipText("Inicia o processo de envio da mensagem usando Go-Back-N");
      jButton1.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
         }
      });

      jFormattedTextField1.setToolTipText("Digite a mensagem a ser enviada (Máx. ");

      jLabel1.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
      jLabel1.setText("Mensagem: (Máx. ");

      pnlSender.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

      javax.swing.GroupLayout pnlSenderLayout = new javax.swing.GroupLayout(pnlSender);
      pnlSender.setLayout(pnlSenderLayout);
      pnlSenderLayout.setHorizontalGroup(
         pnlSenderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGap(0, 1244, Short.MAX_VALUE)
      );
      pnlSenderLayout.setVerticalGroup(
         pnlSenderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGap(0, 66, Short.MAX_VALUE)
      );

      pnlReceiver.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

      javax.swing.GroupLayout pnlReceiverLayout = new javax.swing.GroupLayout(pnlReceiver);
      pnlReceiver.setLayout(pnlReceiverLayout);
      pnlReceiverLayout.setHorizontalGroup(
         pnlReceiverLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGap(0, 1244, Short.MAX_VALUE)
      );
      pnlReceiverLayout.setVerticalGroup(
         pnlReceiverLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGap(0, 60, Short.MAX_VALUE)
      );

      jLabel2.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
      jLabel2.setText("Receiver");

      jLabel3.setFont(new java.awt.Font("Dialog", 0, 12)); // NOI18N
      jLabel3.setText("Sender");

      jLabel4.setFont(new java.awt.Font("Dialog", 1, 11)); // NOI18N
      jLabel4.setForeground(new java.awt.Color(0, 255, 0));
      jLabel4.setText("confirmado");
      jLabel4.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

      jLabel6.setFont(new java.awt.Font("Dialog", 0, 11)); // NOI18N
      jLabel6.setForeground(new java.awt.Color(255, 0, 0));
      jLabel6.setText("reenviando");
      jLabel6.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

      jLabel7.setFont(new java.awt.Font("Dialog", 1, 11)); // NOI18N
      jLabel7.setForeground(new java.awt.Color(0, 0, 255));
      jLabel7.setText("enviado");
      jLabel7.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

      jLabel8.setFont(new java.awt.Font("Dialog", 0, 11)); // NOI18N
      jLabel8.setText("não enviado");
      jLabel8.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));

      jLabel9.setFont(new java.awt.Font("Dialog", 0, 11)); // NOI18N
      jLabel9.setForeground(new java.awt.Color(255, 0, 0));
      jLabel9.setText("reenviado");
      jLabel9.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));

      lbDescartadosErro.setFont(new java.awt.Font("Dialog", 0, 11)); // NOI18N
      lbDescartadosErro.setText("Descartados por erro: 0");
      lbDescartadosErro.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 0, 12))); // NOI18N

      lbForaDeOrdem.setFont(new java.awt.Font("Dialog", 0, 11)); // NOI18N
      lbForaDeOrdem.setText("Recebidos fora de ordem: 0");
      lbForaDeOrdem.setBorder(javax.swing.BorderFactory.createTitledBorder(null, "", javax.swing.border.TitledBorder.DEFAULT_JUSTIFICATION, javax.swing.border.TitledBorder.DEFAULT_POSITION, new java.awt.Font("Dialog", 0, 12))); // NOI18N

      fileMenu.setMnemonic('f');
      fileMenu.setText("File");
      fileMenu.setFont(new java.awt.Font("Dialog", 0, 14));

      exitMenuItem.setFont(new java.awt.Font("Dialog", 0, 14));
      exitMenuItem.setMnemonic('x');
      exitMenuItem.setText("Exit");
      exitMenuItem.addActionListener(new java.awt.event.ActionListener() {
         public void actionPerformed(java.awt.event.ActionEvent evt) {
            exitMenuItemActionPerformed(evt);
         }
      });
      fileMenu.add(exitMenuItem);

      menuBar.add(fileMenu);

      setJMenuBar(menuBar);

      javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
      getContentPane().setLayout(layout);
      layout.setHorizontalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(pnlReceiver, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap())
         .addGroup(layout.createSequentialGroup()
            .addGap(12, 12, 12)
            .addComponent(jLabel1)
            .addContainerGap(1149, Short.MAX_VALUE))
         .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(12, Short.MAX_VALUE)
            .addComponent(jFormattedTextField1, javax.swing.GroupLayout.DEFAULT_SIZE, 1167, Short.MAX_VALUE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jButton1)
            .addGap(12, 12, 12))
         .addGroup(layout.createSequentialGroup()
            .addGap(12, 12, 12)
            .addComponent(jLabel2)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 832, Short.MAX_VALUE)
            .addComponent(jLabel8)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel7)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel6)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel9)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(jLabel4)
            .addContainerGap(12, Short.MAX_VALUE))
         .addGroup(layout.createSequentialGroup()
            .addGap(12, 12, 12)
            .addComponent(jLabel3)
            .addContainerGap(1217, Short.MAX_VALUE))
         .addGroup(layout.createSequentialGroup()
            .addGap(12, 12, 12)
            .addComponent(pnlSender, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addContainerGap(12, Short.MAX_VALUE))
         .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
            .addContainerGap(939, Short.MAX_VALUE)
            .addComponent(lbDescartadosErro)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(lbForaDeOrdem)
            .addContainerGap())
      );
      layout.setVerticalGroup(
         layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
         .addGroup(layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(pnlSender, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
               .addGroup(layout.createSequentialGroup()
                  .addGap(18, 18, 18)
                  .addComponent(jLabel2))
               .addGroup(layout.createSequentialGroup()
                  .addGap(3, 3, 3)
                  .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                     .addComponent(jLabel4)
                     .addComponent(jLabel9)
                     .addComponent(jLabel6)
                     .addComponent(jLabel7)
                     .addComponent(jLabel8))))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addComponent(pnlReceiver, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
               .addComponent(lbDescartadosErro)
               .addComponent(lbForaDeOrdem))
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jLabel1)
            .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
               .addComponent(jButton1)
               .addComponent(jFormattedTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE))
            .addContainerGap())
      );

      pack();
   }// </editor-fold>//GEN-END:initComponents

    private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exitMenuItemActionPerformed
        
        service.shutdownNow();
        System.exit(0);
        
    }//GEN-LAST:event_exitMenuItemActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        prepararPainelReceiver();

        sender.setMensagem(jFormattedTextField1.getText());
        inserirPacotesPainelSender();
        
        service.execute(sender);
    }//GEN-LAST:event_jButton1ActionPerformed

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new DemoProtocoloConfiavel().setVisible(true);
            }
        });
    }
   // Variables declaration - do not modify//GEN-BEGIN:variables
   private javax.swing.JMenuItem exitMenuItem;
   private javax.swing.JMenu fileMenu;
   private javax.swing.JButton jButton1;
   private javax.swing.JFormattedTextField jFormattedTextField1;
   private javax.swing.JLabel jLabel1;
   private javax.swing.JLabel jLabel2;
   private javax.swing.JLabel jLabel3;
   private javax.swing.JLabel jLabel4;
   private javax.swing.JLabel jLabel6;
   private javax.swing.JLabel jLabel7;
   private javax.swing.JLabel jLabel8;
   private javax.swing.JLabel jLabel9;
   private javax.swing.JLabel lbDescartadosErro;
   private javax.swing.JLabel lbForaDeOrdem;
   private javax.swing.JMenuBar menuBar;
   private javax.swing.JPanel pnlReceiver;
   private javax.swing.JPanel pnlSender;
   // End of variables declaration//GEN-END:variables

    private ExecutorService service;
    private ReliableSender sender;
    private ReliableReceiver receiver; 

    private HashMap<Long, JLabel> mapLabelSeqSender = new HashMap<Long, JLabel>();
    private HashMap<Long, JLabel> mapLabelPctSender = new HashMap<Long, JLabel>();

    private HashMap<Long, JLabel> mapLabelSeqReceiver = new HashMap<Long, JLabel>();
    private HashMap<Long, JLabel> mapLabelPctReceiver = new HashMap<Long, JLabel>();
    
    private ParallelGroup grupoHorizontalLabelsSender;
    private ParallelGroup grupoVerticalLabelsSender;
    private ParallelGroup grupoParaleloExternoHorizontalSender;
    private ParallelGroup grupoParaleloExternoVerticalSender;
    private GroupLayout   pnlSenderLayout;

    private ParallelGroup grupoHorizontalLabelsReceiver;
    private ParallelGroup grupoVerticalLabelsReceiver;
    private ParallelGroup grupoParaleloExternoHorizontalReceiver;
    private ParallelGroup grupoParaleloExternoVerticalReceiver;
    private GroupLayout   pnlReceiverLayout;

    private SequentialGroup grupoSequencialHorizontalReceiver;
    private SequentialGroup grupoSequencialVerticalReceiver;
      
    private int descartadosPorErro = 0;
    private int foraDeOrdem = 0;
    
    private void initSpecialComponents() {
       	service = Executors.newFixedThreadPool(2);
         
         sender = new ReliableSender();
         sender.setCommunicationMonitor(this);
         receiver = new ReliableReceiver(); 
         receiver.setCommunicationMonitor(this);
         service.execute(receiver);
    }

    private void configComponents() {
        AbstractDocument doc = (AbstractDocument)jFormattedTextField1.getDocument();
        doc.setDocumentFilter(new DocumentSizeFilter(MAX_CHARACTERS));
        
        jFormattedTextField1.setToolTipText(jFormattedTextField1.getToolTipText() + MAX_CHARACTERS + " caracteres)");
        jLabel1.setText(jLabel1.getText() + MAX_CHARACTERS + " caracteres)");
    }

   private JLabel criarLabelConteudoPacote(String texto) {
      JLabel label = new JLabel(texto);
      label.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
      label.setFont(new java.awt.Font("Dialog", Font.PLAIN, 11)); // NOI18N
      label.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
      return label;
   }
   
   private JLabel criarLabelSequencialPacote(String texto) {
      JLabel label = new JLabel(texto);
      label.setFont(new java.awt.Font("Dialog", Font.PLAIN, 12)); // NOI18N
      label.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
      return label;
      
   }

   public void inserirPacotesPainelSender() {

      pnlSender.removeAll();
      
      pnlSenderLayout = new javax.swing.GroupLayout(pnlSender);
      grupoParaleloExternoHorizontalSender = pnlSenderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
      grupoParaleloExternoVerticalSender = pnlSenderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);

      SequentialGroup grupoSequencialHorizontal = pnlSenderLayout.createSequentialGroup().addContainerGap();
      SequentialGroup grupoSequencialVertical;

      ArrayList<Pacote> lista = sender.getPacotesEmpacotados();

      for (Pacote p : lista) {
         
         JLabel lbPct = criarLabelConteudoPacote(p.getBody());
         JLabel lbSeq = criarLabelSequencialPacote(String.valueOf(p.getSeq()));

         mapLabelSeqSender.put(p.getSeq(), lbSeq);
         mapLabelPctSender.put(p.getSeq(), lbPct);
         
         grupoHorizontalLabelsSender = pnlSenderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
         grupoHorizontalLabelsSender.addComponent(lbSeq, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE);
         grupoHorizontalLabelsSender.addComponent(lbPct);

         grupoVerticalLabelsSender = pnlSenderLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
         grupoVerticalLabelsSender.addComponent(lbSeq);
         grupoVerticalLabelsSender.addComponent(lbPct);
         
         grupoSequencialHorizontal.addGroup(grupoHorizontalLabelsSender);
         
         grupoSequencialVertical = pnlSenderLayout.createSequentialGroup().addContainerGap();
         grupoSequencialVertical
                  .addComponent(lbSeq)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addComponent(lbPct)
                  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
         
         grupoParaleloExternoVerticalSender.addGroup(grupoSequencialVertical);
         
      }

      grupoSequencialHorizontal.addContainerGap(944, Short.MAX_VALUE);

      grupoParaleloExternoHorizontalSender.addGroup(grupoSequencialHorizontal);
         
      pnlSenderLayout.setHorizontalGroup(grupoParaleloExternoHorizontalSender);
      pnlSenderLayout.setVerticalGroup(grupoParaleloExternoVerticalSender);
      pnlSender.setLayout(pnlSenderLayout);

   }

   private void prepararPainelReceiver(){
      pnlReceiver.removeAll();
      
      pnlReceiverLayout = new javax.swing.GroupLayout(pnlReceiver);
      grupoParaleloExternoHorizontalReceiver = pnlReceiverLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
      grupoParaleloExternoVerticalReceiver = pnlReceiverLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
      grupoSequencialHorizontalReceiver = pnlReceiverLayout.createSequentialGroup().addContainerGap();
      grupoSequencialHorizontalReceiver.addContainerGap(944, Short.MAX_VALUE);
      grupoParaleloExternoHorizontalReceiver.addGroup(grupoSequencialHorizontalReceiver);
         
      pnlReceiverLayout.setHorizontalGroup(grupoParaleloExternoHorizontalReceiver);
      pnlReceiverLayout.setVerticalGroup(grupoParaleloExternoVerticalReceiver);
      pnlReceiver.setLayout(pnlReceiverLayout);
      
      descartadosPorErro = 0;
      foraDeOrdem = 0;
   }
   
   public void inserirPacotePainelReceiver(Pacote p) {
         JLabel lbPct = criarLabelConteudoPacote(p.getBody());
         JLabel lbSeq = criarLabelSequencialPacote(String.valueOf(p.getSeq()));

         mapLabelSeqReceiver.put(p.getSeq(), lbSeq);
         mapLabelPctReceiver.put(p.getSeq(), lbPct);
         
         grupoHorizontalLabelsReceiver = pnlReceiverLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
         grupoHorizontalLabelsReceiver.addComponent(lbSeq, javax.swing.GroupLayout.PREFERRED_SIZE, 24, javax.swing.GroupLayout.PREFERRED_SIZE);
         grupoHorizontalLabelsReceiver.addComponent(lbPct);

         grupoVerticalLabelsReceiver = pnlReceiverLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING);
         grupoVerticalLabelsReceiver.addComponent(lbSeq);
         grupoVerticalLabelsReceiver.addComponent(lbPct);
         
         grupoSequencialHorizontalReceiver.addGroup(grupoHorizontalLabelsReceiver);
         
         grupoSequencialVerticalReceiver = pnlReceiverLayout.createSequentialGroup().addContainerGap();
         grupoSequencialVerticalReceiver
                  .addComponent(lbSeq)
                  .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                  .addComponent(lbPct)
                  .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
         
         grupoParaleloExternoVerticalReceiver.addGroup(grupoSequencialVerticalReceiver);

         pnlReceiverLayout.setHorizontalGroup(grupoParaleloExternoHorizontalReceiver);
         pnlReceiverLayout.setVerticalGroup(grupoParaleloExternoVerticalReceiver);
         pnlReceiver.setLayout(pnlReceiverLayout);
   }   
   
   @Override
   public void packetSent(Pacote p) {
      JLabel label = mapLabelPctSender.get(p.getSeq());
      label.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
      label.setFont(new java.awt.Font("Dialog", Font.ITALIC, 11));
      label.setForeground(Color.blue);

   }

   @Override
   public void packetReceived(Pacote p) {
      
      inserirPacotePainelReceiver(p);
      
   }
   
   @Override
   public void packetAcknowledged(Pacote p) {
      JLabel label = mapLabelPctSender.get(p.getSeq());
      label.setFont(new java.awt.Font("Dialog", Font.BOLD, 11));
      label.setForeground(Color.GREEN);
      label.setEnabled(true);
   }

   @Override
   public void packetReSent(Pacote p) {
      JLabel label = mapLabelPctSender.get(p.getSeq());
      label.setForeground(Color.red);
      label.setFont(new java.awt.Font("Dialog", Font.PLAIN, 11));
      label.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.RAISED));
      label.setEnabled(true);
      
      try {
         Thread.sleep(50);
      } catch (InterruptedException ex) {}
      
      label.setEnabled(true);
      label.setBorder(new javax.swing.border.SoftBevelBorder(javax.swing.border.BevelBorder.LOWERED));
      label.setFont(new java.awt.Font("Dialog", Font.ITALIC, 11));
      label.setForeground(Color.red);
   }

   @Override
   public void packetDiscardedChecksumError(Pacote p) {
      lbDescartadosErro.setText("Descartados por erro: " + ++descartadosPorErro);
   }

   @Override
   public void packetDiscardedOutOfOrder(Pacote p) {
      lbForaDeOrdem.setText("Recebidos fora de ordem: " + ++foraDeOrdem);
   }

    public class DocumentSizeFilter extends DocumentFilter {
        int maxCharacters;

        public DocumentSizeFilter(int maxChars) {
            maxCharacters = maxChars;
        }

        @Override
        public void insertString(FilterBypass fb, int offs,
                                 String str, AttributeSet a)
            throws BadLocationException {

            //This rejects the entire insertion if it would make
            //the contents too long. Another option would be
            //to truncate the inserted string so the contents
            //would be exactly maxCharacters in length.
            if ((fb.getDocument().getLength() + str.length()) <= maxCharacters)
                super.insertString(fb, offs, str, a);
            else
                Toolkit.getDefaultToolkit().beep();
        }

        @Override
        public void replace(FilterBypass fb, int offs,
                            int length, 
                            String str, AttributeSet a)
            throws BadLocationException {
            //This rejects the entire replacement if it would make
            //the contents too long. Another option would be
            //to truncate the replacement string so the contents
            //would be exactly maxCharacters in length.
            if ((fb.getDocument().getLength() + str.length()
                 - length) <= maxCharacters)
                super.replace(fb, offs, length, str, a);
            else
                Toolkit.getDefaultToolkit().beep();
        }

    }    
}
